/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufba.lasid.jitclouds.mda.datatypes;

import br.ufba.lasid.jitclouds.mda.api.EState;
import br.ufba.lasid.jitclouds.mda.api.ICommunicationBus;
import br.ufba.lasid.jitclouds.mda.api.IFailureDetector;
import br.ufba.lasid.jitclouds.mda.api.IReplicaHandler;
import java.util.Hashtable;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author aliriosa
 */
public class Peer2PeerFailureDetector /*implements IFailureDetector*/{

    String rid;
    EState state = EState.UNKNOWN;
    
    ICommunicationBus comm;
    long period = 10L;
    long timeout = 100L;
    
    class Monitor extends Thread{

        boolean stopped = false;
        
        @Override
        public void run() {
            stopped = false;
            new Thread(new Sender()).start();
        }
        
        class Sender implements Runnable{

            @Override
            public void run() {
                try{
                    while(!stopped){

                        try {

                            FDMessage m = new FDMessage(rid,  null, FDMessage.FD_QUERY);
                            comm.send(m);

                            new Thread(new Receiver(timeout)).start();

                        } catch (Exception ex) {
                            Logger.getLogger(Peer2PeerFailureDetector.class.getName()).log(Level.SEVERE, null, ex);
                        }
                        Thread.sleep(period);
                    }
                }catch(Exception ex){
                    Logger.getLogger(Peer2PeerFailureDetector.class.getName()).log(Level.SEVERE, null, ex);                
                }
            }        
        }

        class Receiver implements Runnable{

            private long timeout;

            public Receiver(long timeout) {
                this.timeout = timeout;
            }

            @Override
            public void run() {
                try {
                    FDMessage m = comm.receive(this.timeout);

                    EState status = EState.CRASHED;
                    if(m!= null){
                        if(m.body != null && !m.body.equals("error")){
                            state = EState.WORKING;
                        }
                    }                                        
                } catch (Exception ex) {
                    Logger.getLogger(Peer2PeerFailureDetector.class.getName()).log(Level.SEVERE, null, ex);
                }

            }

        }
        
        
    }
    
    class Monitored extends Thread{
        
    }

//    @Override
//    public EState query() throws Exception{
//        return state;
//    }
//
//    @Override
//    public void register(IReplicaHandler handler) throws Exception{
//        rid = handler.getID() + "@" + handler.getLocation();
//    }
//    
//    public void start(){
//        new Thread(new Sender()).start();
//    }
//        
//    
    public class FDMessage{
        static final String FD_QUERY = "FD_QUERY";
        String from = null;
        String to = null;
        String body = null;

        public FDMessage(String from, String to, String body) {
            this.from = from;
            this.to = to;
            this.body = body;
        }        
        
    }
////    ICommunicationBus comm;
////    protected long timeout = 1L;
////    
////
////    public Peer2PeerFailureDetector(IGroupView group, ICommunicationBus comm) {
////        this.group = group;
////        this.comm = comm;
////    }
////
////    public long getTimeout() {
////        return timeout;
////    }
////
////    public void setTimeout(long timeout) {
////        this.timeout = timeout;
////    }
////
////    
////    @Override
////    public EState queryStatus(String resourceID) throws Exception {
////        
////        for(IReplicaHandler replica : group){
////            comm.send("QUERYSTATUS", replica.getLocation());
////        }
////        
////        EState state = comm.receive(resourceID, timeout);
////        
////        if(state == null){
////            state = EState.CRASHED;
////        }
////        return state;
////    }
////
////    @Override
////    public void informStatus(String resourceID) throws Exception {
////        comm.send(EState.WORKING, resourceID);
////    }
    
}
